package com.esunny.resourcevisualization.service.impl;

import com.esunny.resourcevisualization.constant.EntityUsingStatus;
import com.esunny.resourcevisualization.constant.TableName;
import com.esunny.resourcevisualization.domain.entity.ResourceTypeEntity;
import com.esunny.resourcevisualization.domain.entity.ResourceTypeEntityData;
import com.esunny.resourcevisualization.domain.entity.UserEntity;
import com.esunny.resourcevisualization.domain.request.PageData;
import com.esunny.resourcevisualization.domain.request.QueryEntityDto;
import com.esunny.resourcevisualization.domain.request.QueryEntityListDto;
import com.esunny.resourcevisualization.domain.response.ReturnStructure;
import com.esunny.resourcevisualization.manage.*;
import com.esunny.resourcevisualization.service.ResourceTypeEntityService;
import com.esunny.resourcevisualization.util.HostHolder;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

/**
 * @version 1.0.0.0
 * @ClassName ResourceTypeEntityServiceImpl
 * @Description 资源类别实体服务类
 * @Author baochencong
 * @Date 2020/9/28 14:53
 */
@Service
public class ResourceTypeEntityServiceImpl implements ResourceTypeEntityService {

    @Resource
    private HostHolder hostHolder;

    @Resource
    private UserManage userManage;

    @Resource
    private UserEntityManage userEntityManage;

    @Resource
    private ResourceTypeEntityDataManage resourceTypeEntityDataManage;

    @Resource
    private ResourceTypeEntityManage resourceTypeEntityManage;

    private static Logger LOGGER = LoggerFactory.getLogger(ResourceTypeEntityService.class);

    @Resource
    private ResourceTypeEntityEntityDataManage resourceTypeEntityEntityDataManage;

    @Override
    public ReturnStructure addResourceTypeEntity(ResourceTypeEntity resourceTypeEntity) {
        formatEntityStatusTitleToName(resourceTypeEntity);
        return resourceTypeEntityManage.addResourceTypeEntity(resourceTypeEntity);
    }

    @Override
    public ReturnStructure deleteResourceTypeEntityByEntityId(int entityId) {
        if (isExistedResourceTypeEntityByEntityId(entityId)) {
            return resourceTypeEntityEntityDataManage.deleteResourceTypeEntityByEntityId(entityId);
        }
        return ReturnStructure.ERROR("资源类别实体不存在", null);
    }

    @Override
    public ReturnStructure updateResourceTypeEntityByEntityId(@NotNull ResourceTypeEntity resourceTypeEntity) {
        resourceTypeEntity.setLastEditedBy(hostHolder.getUser().getUsername());
        resourceTypeEntity.setLastEditedTime(new Timestamp(System.currentTimeMillis()));
        int entityId = resourceTypeEntity.getResourceTypeEntityId();
        if (isExistedResourceTypeEntityByEntityId(entityId)) {
            formatEntityStatusTitleToName(resourceTypeEntity);
            return resourceTypeEntityManage.updateResourceTypeEntityByEntityId(resourceTypeEntity);
        }
        return ReturnStructure.ERROR("资源类别实体不存在", null);
    }

    @Override
    public ReturnStructure markDeleteResourceTypeEntityByEntityId(int entityId) {
        return resourceTypeEntityManage.markDeleteResourceTypeEntityByEntityId(entityId);
    }

    @Override
    public ResourceTypeEntity getResourceTypeEntityByEntityId(int entityId) {
        return resourceTypeEntityManage.getResourceTypeEntityByEntityId(entityId);
    }

    @Override
    public List<ResourceTypeEntity> getResourceTypeEntityListByName(String name) {
        List<ResourceTypeEntity> resourceTypeEntityListByName = resourceTypeEntityManage.getResourceTypeEntityListByName(name);
        formatUserNameToTitle(resourceTypeEntityListByName);
        formatEntityStatusNameToTitle(resourceTypeEntityListByName);
        return resourceTypeEntityListByName;
    }

    @Override
    public PageData<ResourceTypeEntity> getResourceEntityPageListByName(PageData<ResourceTypeEntity> pageData, String name) {
        pageData.setStartIndex();
        List<ResourceTypeEntity> resourceTypeEntityListByName = resourceTypeEntityManage.getResourceEntityPageListByName(pageData, name);
        formatUserNameToTitle(resourceTypeEntityListByName);
        formatEntityStatusNameToTitle(resourceTypeEntityListByName);

        pageData.setTotalSize(resourceTypeEntityManage.getResourceEntityTotalSizeByName(name));
        pageData.setPageDataList(resourceTypeEntityListByName);
        return pageData;
    }

    @Override
    public List<ResourceTypeEntity> getMayApplyEntityList(ResourceTypeEntity resourceTypeEntity) {
        List<ResourceTypeEntity> mayApplyEntityList = resourceTypeEntityManage.getMayApplyEntityList(resourceTypeEntity);
        formatUserNameToTitle(mayApplyEntityList);
        formatEntityStatusNameToTitle(mayApplyEntityList);
        return mayApplyEntityList;
    }

    @Override
    public ResourceTypeEntity getResourceTypeEntityByEntityIdAndName(int entityId, String name) {
        ResourceTypeEntity resourceTypeEntityByEntityIdAndName = resourceTypeEntityManage.getResourceTypeEntityByEntityIdAndName(entityId, name);
        if (resourceTypeEntityByEntityIdAndName != null) {
            formatUserNameToTitle(resourceTypeEntityByEntityIdAndName);
        }
        return resourceTypeEntityByEntityIdAndName;
    }

    @Override
    public List<ResourceTypeEntity> getResourceTypeEntityList() {
        return resourceTypeEntityManage.getResourceTypeEntityList();
    }

    @Override
    public List<ResourceTypeEntity> getResourceTypeEntityListByCreated(String createdBy) {
        return resourceTypeEntityManage.getResourceTypeEntityListByCreated(createdBy);
    }

    @Override
    public List<ResourceTypeEntity> queryResourceTypeEntityList(QueryEntityListDto queryEntityListDto) {

        ResourceTypeEntity resourceTypeEntity = getQueryEntity(queryEntityListDto);
        List<ResourceTypeEntity> entityList = resourceTypeEntityManage.queryResourceTypeEntityList(resourceTypeEntity);

        for (QueryEntityDto queryEntityDto : queryEntityListDto.getQueryEntityDtoList()) {
            if (queryEntityDto.isDynamics()) {
                List<ResourceTypeEntity> resourceTypeEntities = new ArrayList<>();
                if (queryEntityDto.getTableName().equals(TableName.RESOURCE_TYPE_FIELD)) {
                    List<ResourceTypeEntityData> resourceTypeEntityDataByNameAndFieldName = resourceTypeEntityDataManage.getResourceTypeEntityDataByNameAndFieldNameAndValue(queryEntityListDto.getResourceTypeName(), queryEntityDto.getFieldName(), queryEntityDto.getFieldValue());
                    for (ResourceTypeEntityData data : resourceTypeEntityDataByNameAndFieldName) {
                        ResourceTypeEntity resourceTypeEntityByEntityId = resourceTypeEntityManage.getResourceTypeEntityByEntityId(data.getResourceTypeEntityId());
                        if (resourceTypeEntityByEntityId != null) {
                            resourceTypeEntities.add(resourceTypeEntityByEntityId);
                        }
                    }
                } else if (queryEntityDto.getTableName().equals(TableName.USER_ENTITY)) {
                    List<UserEntity> userEntityListByUsername = userEntityManage.getUserEntityListByUsername(queryEntityDto.getFieldValue());
                    for (UserEntity data : userEntityListByUsername) {
                        ResourceTypeEntity resourceTypeEntityByEntityId = resourceTypeEntityManage.getResourceTypeEntityByEntityId(data.getEntityId());
                        if (resourceTypeEntityByEntityId != null) {
                            resourceTypeEntities.add(resourceTypeEntityByEntityId);
                        }
                    }
                }
                entityList.retainAll(resourceTypeEntities);
            }
        }
        formatEntityStatusNameToTitle(entityList);

        return entityList;
    }

    @Override
    public PageData<ResourceTypeEntity> queryResourceEntityPageList(QueryEntityListDto queryEntityListDto) {
        List<ResourceTypeEntity> resourceTypeEntities = queryResourceTypeEntityList(queryEntityListDto);
        formatUserNameToTitle(resourceTypeEntities);
        PageData<ResourceTypeEntity> pageData = new PageData<>();
        pageData.setTotalSize(resourceTypeEntities.size());
        pageData.setCurrentPage(queryEntityListDto.getCurrentPage());
        pageData.setPageSize(queryEntityListDto.getPageSize());
        if (resourceTypeEntities.size() - pageData.getStartIndex() <= pageData.getPageSize()) {
            pageData.setPageDataList(resourceTypeEntities.subList(pageData.getStartIndex(), resourceTypeEntities.size()));
        } else {
            pageData.setPageDataList(resourceTypeEntities.subList(pageData.getStartIndex(), pageData.getStartIndex()+pageData.getPageSize()));
        }
        return pageData;
    }

    /**
     * 得到查找实体的动态条件
     *
     * @param queryEntityListDto 所有动态条件
     * @return 查找实体表的动态条件
     */
    private ResourceTypeEntity getQueryEntity(@NotNull QueryEntityListDto queryEntityListDto) {
        ResourceTypeEntity resourceTypeEntity = new ResourceTypeEntity();
        String resourceTypeName = queryEntityListDto.getResourceTypeName();
        resourceTypeEntity.setResourceTypeName(resourceTypeName);

        for (QueryEntityDto queryEntityDto : queryEntityListDto.getQueryEntityDtoList()) {
            if (queryEntityDto.getTableName().equals(TableName.RESOURCE_TYPE_ENTITY)) {
                String fieldName = queryEntityDto.getFieldName();
                if (fieldName.equals("mayApply")){
                    resourceTypeEntity.setMayApply(String.valueOf(queryEntityDto.getFieldValue()).equals("true"));
                    continue;
                }
                fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                try {
                    Method method = ResourceTypeEntity.class.getDeclaredMethod("set" + fieldName, queryEntityDto.getFieldType().equals("int") ? int.class : String.class);
                    method.invoke(resourceTypeEntity, queryEntityDto.getFieldType().equals("int") ? Integer.parseInt(queryEntityDto.getFieldValue()) : queryEntityDto.getFieldValue());
                } catch (NoSuchMethodException e) {
                    LOGGER.error("我没有获取到set方法");
                } catch (IllegalAccessException e) {
                    LOGGER.error("非法接口异常");
                } catch (InvocationTargetException e) {
                    LOGGER.error("无效目标异常");
                }
            }
        }
        return resourceTypeEntity;
    }

    @Override
    public List<ResourceTypeEntity> getResourceTypeEntityListByLastEdited(String lastEditedBy) {
        return resourceTypeEntityManage.getResourceTypeEntityListByLastEdited(lastEditedBy);
    }

    @Override
    public List<ResourceTypeEntity> getResourceTypeEntityListByNameAndCreated(String name, String createdBy) {
        return resourceTypeEntityManage.getResourceTypeEntityListByNameAndCreated(name, createdBy);
    }

    @Override
    public List<ResourceTypeEntity> getResourceTypeEntityListByNameAndLastEdited(String name, String lastEditedBy) {
        return resourceTypeEntityManage.getResourceTypeEntityListByNameAndLastEdited(name, lastEditedBy);
    }

    @Override
    public List<ResourceTypeEntity> getResourceTypeEntityListByNameAndStatus(String name, String status) {
        return resourceTypeEntityManage.getResourceTypeEntityListByNameAndStatus(name, status);
    }

    @Override
    public ReturnStructure updateResourceTypeEntityStatusById(ResourceTypeEntity resourceTypeEntity) {
        if (!isExistedResourceTypeEntityByEntityId(resourceTypeEntity.getResourceTypeEntityId())) {
            return ReturnStructure.NOT_FOUND("该实体不存在", null);
        }
        return resourceTypeEntityManage.updateResourceTypeEntityStatusById(resourceTypeEntity);
    }


    /**
     * 通过资源类别实体id判断资源类别实体是否存在
     *
     * @param entityId 资源类别实体id
     * @return 资源类别实体
     */
    private boolean isExistedResourceTypeEntityByEntityId(int entityId) {
        return resourceTypeEntityManage.getResourceTypeEntityByEntityId(entityId) != null;
    }

    /**
     * 格式化用户名到中文名
     *
     * @param resourceTypeEntity 资源实体信息
     */
    private void formatUserNameToTitle(@NotNull ResourceTypeEntity resourceTypeEntity) {
        if (resourceTypeEntity.getCreatedBy().equals("admin")) {
            resourceTypeEntity.setCreatedBy("管理员");
        } else {
            resourceTypeEntity.setCreatedBy(userManage.getUserByName(resourceTypeEntity.getCreatedBy()).getRealName());
        }
        if (resourceTypeEntity.getLastEditedBy().equals("admin")) {
            resourceTypeEntity.setLastEditedBy("管理员");
        } else {
            resourceTypeEntity.setLastEditedBy(userManage.getUserByName(resourceTypeEntity.getLastEditedBy()).getRealName());
        }
    }

    /**
     * 格式化用户名到中文名
     *
     * @param resourceTypeEntityListByName 资源实体列表信息
     */
    private void formatUserNameToTitle(@NotNull List<ResourceTypeEntity> resourceTypeEntityListByName) {
        for (ResourceTypeEntity entityInfo : resourceTypeEntityListByName) {
            formatUserNameToTitle(entityInfo);
        }
    }

    /**
     * 格式化资源实体状态
     *
     * @param resourceTypeEntityList 资源实体列表信息
     */
    private void formatEntityStatusNameToTitle(@NotNull List<ResourceTypeEntity> resourceTypeEntityList) {
        for (ResourceTypeEntity eachEntity : resourceTypeEntityList) {
            for (int statusIndex = 0; statusIndex < EntityUsingStatus.usingStatusNameList.length; statusIndex++) {
                if (eachEntity.getStatus().equals(EntityUsingStatus.usingStatusNameList[statusIndex])) {
                    eachEntity.setStatus(EntityUsingStatus.usingStatusTitleList[statusIndex]);
                }
            }
        }
    }

    /**
     * 格式化资源实体状态
     *
     * @param resourceTypeEntity 资源实体信息
     */
    private void formatEntityStatusTitleToName(@NotNull ResourceTypeEntity resourceTypeEntity) {
        for (int statusIndex = 0; statusIndex < EntityUsingStatus.usingStatusTitleList.length; statusIndex++) {
            if (resourceTypeEntity.getStatus().equals(EntityUsingStatus.usingStatusTitleList[statusIndex])) {
                resourceTypeEntity.setStatus(EntityUsingStatus.usingStatusNameList[statusIndex]);
            }
        }
    }
}
